package com.shengqin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shengqin.entity.Plan;
import com.shengqin.entity.SysHealthProject;
import com.shengqin.entity.TestResult;
import com.shengqin.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class TestResultHandlerServiceImpl implements ITestResultHandlerService {

    @Resource
    private ITestResultService testResultService;
    @Resource
    private SysHealthProjectService healthProjectService;
    @Resource
    private IStandardService standardService;
    @Resource
    private IPlanService planService;

    private static final String TIMING_PROJECT = "计时";
    private static final String BMI_PROJECT = "BMI";
    private static final String HEIGHT_PROJECT = "身高";
    private static final String WEIGHT_PROJECT = "体重";
    private static final String RESULT_SEPARATOR = "/";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleRuleTypeOne(TestResult testResult, TestResult existingResult, Integer planId) {
        testResultService.removeById(existingResult.getId());
        saveTestResult(testResult, planId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleRuleTypeTwo(TestResult testResult, TestResult existingResult, Plan plan) {
        int scoreComparison = testResult.getFinalScore().compareTo(existingResult.getFinalScore());
        if (scoreComparison > 0) {
            updateTestResult(testResult, existingResult, plan.getId());
        } else if (scoreComparison == 0) {
            String projectType = getProjectType(testResult, plan);
            if (isTimingProject(projectType)) {
                // 计时项目，成绩越小越好
                try {
                    BigDecimal newResult = transferResult(testResult.getResult());
                    BigDecimal oldResult = transferResult(existingResult.getResult());
                    if (newResult != null && oldResult != null && newResult.compareTo(oldResult) < 0) {
                        updateTestResult(testResult, existingResult, plan.getId());
                    }
                } catch (Exception e) {
                    log.error("比较计时项目成绩出错, testResult={}, existingResult={}", testResult, existingResult, e);
                }
            } else {
                // 非计时项目，成绩越大越好
                try {
                    BigDecimal newResult = new BigDecimal(testResult.getResult());
                    BigDecimal oldResult = new BigDecimal(existingResult.getResult());
                    if (newResult.compareTo(oldResult) > 0) {
                        updateTestResult(testResult, existingResult, plan.getId());
                    }
                } catch (Exception e) {
                    log.error("比较非计时项目成绩出错, testResult={}, existingResult={}", testResult, existingResult, e);
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveTestResult(TestResult testResult, Integer planId) {
        testResult.setCreateTime(LocalDateTime.now());
        testResultService.save(testResult);
    }

    private void updateTestResult(TestResult testResult, TestResult existingResult, Integer planId) {
        testResult.setId(existingResult.getId());
        testResultService.updateById(testResult);
    }

    private String getProjectType(TestResult testResult, Plan plan) {
        SysHealthProject healthProject = healthProjectService.listByPrjCodeAndGradeId(
            testResult.getPrjName(), 
            String.valueOf(testResult.getGradeId()),
            plan.getTemplateId()
        );
        return healthProject != null ? healthProject.getPrjType() : null;
    }

    private boolean isTimingProject(String projectType) {
        return StringUtils.hasLength(projectType) && 
               (projectType.contains(TIMING_PROJECT) || projectType.equalsIgnoreCase(TIMING_PROJECT));
    }

    private BigDecimal transferResult(String result) {
        if (StringUtils.hasLength(result)) {
            if (result.contains(":")) {
                result = result.replaceAll("\\.", ":");
                String[] texts = result.split(":");
                BigDecimal minutes = new BigDecimal(Integer.parseInt(texts[0]) * 60);
                BigDecimal second = new BigDecimal(Integer.parseInt(texts[1]));
                BigDecimal millisecond = new BigDecimal(Integer.parseInt(texts[2]))
                    .divide(new BigDecimal("1000"), 3, RoundingMode.DOWN);
                return minutes.add(second).add(millisecond);
            } else if (result.contains("′") || result.contains("'")) {
                String finalValue = result.replaceAll("'", "′")
                                       .replaceAll("\"", "″");

                String[] values = finalValue.split("′");
                Integer valueMin = Integer.parseInt(values[0]) * 60;
                Integer valueSecond = Integer.valueOf(values[1].replaceAll("″", ""));
                return new BigDecimal(valueMin + valueSecond);
            } else {
                return new BigDecimal(result);
            }
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleBmiResult(TestResult bmiResult, List<TestResult> heightWeightResults, Integer planId) {
        try {
            // 2. 查找已存在的 BMI、身高、体重记录
            QueryWrapper<TestResult> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(TestResult::getPlanId, planId)
                    .eq(TestResult::getStudyCode, bmiResult.getStudyCode())
                    .in(TestResult::getPrjName, Arrays.asList(BMI_PROJECT, HEIGHT_PROJECT, WEIGHT_PROJECT));
            List<TestResult> existingResults = testResultService.list(queryWrapper);

            if(bmiResult.getPrjName().equalsIgnoreCase(BMI_PROJECT) && !CollectionUtils.isEmpty(heightWeightResults)){
                List<TestResult> bmiResultList = new ArrayList<>();
                // 3. 如果存在旧记录，删除它们
                if (!CollectionUtils.isEmpty(existingResults)) {
                    List<Long> existingIds = existingResults.stream()
                            .map(TestResult::getId)
                            .collect(Collectors.toList());
                    testResultService.removeByIds(existingIds);
                }

                // 4. 保存新的 BMI 记录
                bmiResult.setCreateTime(LocalDateTime.now());
                bmiResult.setPrjCode("4"); // BMI的项目代码

                bmiResultList.add(bmiResult);
                bmiResultList.addAll(heightWeightResults);
                testResultService.saveBatch(bmiResultList);
            }

        } catch (Exception e) {
            log.error("处理BMI成绩出错, bmiResult={}", bmiResult, e);
            throw e;
        }
    }
} 